package org.wdm.beans;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 *
 * @author iakopap
 */
public class BusDeparture {

    //Simple date format parser
    private static final SimpleDateFormat DATE_FORMAT;
    //Bustop identifier
    private String atcocode;
    //Bustop sms identifier
    private String smscode;
    //Http request time of the transport api live service
    private String requestTime;
    //Mode of the transoprt, e.g. bus or tube
    private String mode;
    //Number of the bus
    private String line;
    //Direction of the route
    private String direction;
    //Operator identifier of the bus
    private String operator;
    //Schedule departured time
    private String aimedDepartureTime;
    //Expected departure time
    private String expectedDepartureTime;
    //Estimated departure time
    private String bestDepartureEstimate;
    //Where this data coming from
    private String source;

    static {
        DATE_FORMAT = new SimpleDateFormat("HH:mm");
        DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
    }

    public BusDeparture(String atcocode, String smscode, String requestTime, String mode, String line, String direction, String operator, String aimedDepartureTime, String expectedDepartureTime, String bestDepartureEstimate, String source) {
        this.atcocode = atcocode;
        this.smscode = smscode;
        this.requestTime = requestTime;
        this.mode = mode;
        this.line = line;
        this.direction = direction;
        this.operator = operator;
        this.aimedDepartureTime = aimedDepartureTime;
        this.expectedDepartureTime = expectedDepartureTime;
        this.bestDepartureEstimate = bestDepartureEstimate;
        this.source = source;
    }

    public String getAimedDepartureTime() {
        return aimedDepartureTime;
    }

    public void setAimedDepartureTime(String aimedDepartureTime) {
        this.aimedDepartureTime = aimedDepartureTime;
    }

    public String getAtcocode() {
        return atcocode;
    }

    public void setAtcocode(String atcocode) {
        this.atcocode = atcocode;
    }

    public String getBestDepartureEstimate() {
        return bestDepartureEstimate;
    }

    public void setBestDepartureEstimate(String bestDepartureEstimate) {
        this.bestDepartureEstimate = bestDepartureEstimate;
    }

    public String getDirection() {
        return direction;
    }

    public void setDirection(String direction) {
        this.direction = direction;
    }

    public String getExpectedDepartureTime() {
        return expectedDepartureTime;
    }

    public void setExpectedDepartureTime(String expectedDepartureTime) {
        this.expectedDepartureTime = expectedDepartureTime;
    }

    public String getLine() {
        return line;
    }

    public void setLine(String line) {
        this.line = line;
    }

    public String getMode() {
        return mode;
    }

    public void setMode(String mode) {
        this.mode = mode;
    }

    public String getOperator() {
        return operator;
    }

    public void setOperator(String operator) {
        this.operator = operator;
    }

    public String getSmscode() {
        return smscode;
    }

    public void setSmscode(String smscode) {
        this.smscode = smscode;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public String getWaitTime() {
        String waitTime = null;
        try {
            //Creating the request time calendar
            int beginIndex = requestTime.indexOf("T");
            String time = requestTime.substring(beginIndex + 1, beginIndex + 6);
            Date start = DATE_FORMAT.parse(time);
            Calendar startCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
            startCalendar.setTime(start);

            //Creating the aimed time calendar
            Date end = DATE_FORMAT.parse(aimedDepartureTime);
            Calendar endCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
            endCalendar.setTime(end);

            //Getting the difference in HH:mm format as wait time
            waitTime = DATE_FORMAT.format(endCalendar.getTimeInMillis() - startCalendar.getTimeInMillis());
        } catch (ParseException pe) {
            return null;
        }

        return waitTime;
    }

    public String getExpectedWaitTime() {
        String waitTime = null;
        try {
            //Creating the request time calendar
            int beginIndex = requestTime.indexOf("T");
            String time = requestTime.substring(beginIndex + 1, beginIndex + 6);
            Date start = DATE_FORMAT.parse(time);
            Calendar startCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
            startCalendar.setTime(start);

            //Creating the expected time calendar
            Date end = DATE_FORMAT.parse(expectedDepartureTime);
            Calendar endCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
            endCalendar.setTime(end);

            //Getting the difference in HH:mm format as wait time
            waitTime = DATE_FORMAT.format(endCalendar.getTimeInMillis() - startCalendar.getTimeInMillis());
        } catch (ParseException pe) {
            return null;
        } catch(NullPointerException npe) {
            return null;
        }

        return waitTime;
    }

    public String getEstimateWaitTime() {
        String waitTime = null;
        try {
            //Creating the request time calendar
            int beginIndex = requestTime.indexOf("T");
            String time = requestTime.substring(beginIndex + 1, beginIndex + 6);
            Date start = DATE_FORMAT.parse(time);
            Calendar startCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
            startCalendar.setTime(start);

            //Creating the estimated time calendar
            Date end = DATE_FORMAT.parse(bestDepartureEstimate);
            Calendar endCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
            endCalendar.setTime(end);

            //Getting the difference in HH:mm format as wait time
            waitTime = DATE_FORMAT.format(endCalendar.getTimeInMillis() - startCalendar.getTimeInMillis());
        } catch (ParseException pe) {
            return null;
        }

        return waitTime;
    }

    @Override
    public String toString() {
        return mode + "(" + line + ")" + " @ stop(" + atcocode + ") in " + requestTime +
                " aimed at " + aimedDepartureTime + "(" + getWaitTime() + ")" +
                ", expected at ~" + expectedDepartureTime + "(" + getExpectedWaitTime() + ")" +
                ", estimated at ~" + bestDepartureEstimate + "(" + getEstimateWaitTime() + ")";
    }
}
